Функциональные возможности

  • Печать

  • Штамп

  • Конвертация


Печать

В режиме печати происходит получения шаблона и json из входных данных.

возможна обработка двух типов docx и html

Будем рассматривать на примере шаблона docx.

Заполнение шаблонного документа docx формата данными из json формата. значения заключенные в двойные фигурные скобки внутри docx заменяются на соответствующие значения из json
Пример:

Тело docx документа

Директору ООО Шайки-лейки
 
от {{document.applicant.lastName}} {{document.applicant.firstName}} {{document.applicant.middleName}}
 
жалоба.
 
Доношу до вашего сведения информацию об отвратительном состоянии инвентаря в бане № {{document.subject_number}}
Полки не мыты. Полы залиты. 
Крайне недоволен. Исправьте ситуацию.
 
{{document.date}}  {{document.applicant.shortFIO}}


Данные в виде json

{
 "document":
  {
    "applicant":
     {
      "firstName": "Иван",
      "lastName": "Иванов",
      "middleName": "Иванович"
     },
     "subject_number": 4,
     "shortFIO":"Иванов И. И.",
     "date":"03.01.2023"
  }
}



Штамп

в режиме штамп на входящий документ накладывается дополнительный текст, а также сформированное изображение из сертификата, которое отражает инициалы подписавшего  и срок действия сертификата

Возможные типы входящих документов для версии 2.0.0 

pdf, docx

Штамп успешно накладывается и регулируется входными и параметрами настройки в случае,

если  контент внутри документа является текстовым.

Если внутри документа содержится изображение масштабированное на весь лист (например скан), то для такого документа корректное наложение штампа  не предусмотрено.


Параметры для наложения штампа на документ следующие


certificate - Сертификат подписанта в Base64
s3url - ссылка на s3, например s3://bucket/templateResolution-b559615a-af21-417f-9a63-e5f6eca42342.docx
stampWidth - ширина штампа в пикселях (если не указано, то по умолчанию 220)
stampHeight - высота штампа в пикселях (если не указано, то по умолчанию 85)
stampAlign - размещение штампа на странице (если не указано, по умолчанию справа [LEFT/RIGHT])
rightText - Текст для вывода слева от штампа
leftText - Текст для вывода слева от штампа

pageNumber - Номер страницы для печати (Последняя страница по дефолту)
leftMargin - Отступ от левого края для текста слева страницы (в символах)
rightMargin - Отступ от правого края для текста справа страницы (в символах)


Также предусмотрен функционал совместной последовательной печати и штампа.


Конвертация

Под конвертацией понимается преобразование одного типа документа в другой.

В данный момент возможны следующие направления конвертации:

HTML → PDF

HTML → DOCX

DOCX  → PDF


В любом из функциональных возможностей обязательно указание направление конвертации

 в виде двух параметров 

inputFormat

outputFormat

inputFormat для функционала Печать также позволяет определить тип передаваемого шаблона

outputFormat указывает в какой тип файла будет в результате.

Если указанные параметры конвертации будут указаны неверно, то возникает ошибка с указанием о этом.


Режимы работы

Кафка

В режиме работы через kafka, выполняется разбор сообщений поступающих в топики

printer.process.print - функционала печати

printer.process.stamp -  функционал штампа

printer.process.print-stamp - функционал последовательного применения печати и штампа


Выполняется функциональное действие соответствующее  каждому топику

Результат в виде готового файла размещается в хранилище s3, ссылка на результат прикладывается в отчет о выполнении.

Сам отчет в виде сообщения кафки публикуется в топик printer.report


Функционалы печать, штамп, печать+штамп  можно включить или выключить в зависимости от настроек экземпляра сервиса, которые требуются для него.

При масштабирования сервиса, возможна конкуренция за вычитку сообщений из топиков, поэтому для каждого экземпляра назначается свой consumer-group-id, на основе переменной окружения POD_NAME.

Также добавлена возможность идемпотентной обработки (MODE_KAFKA_IDEMPOTENCY), для избежания дублирующих  заданий на печать/штамп с последующим результатом в s3 и топик  printer.report

Предусмотрен таймаут выполнения одного задания при работе через kafka (KAFKA_PRINT_TASK_EXECUTION=4m)


HTTP REST

В этом варианте присутствуют два режима обработки, синхронный и асинхронный.

В синхронном режиме входными параметрами являются шаблон и json-параметры для функционала печати,

для функционала штампа документ и параметры штампа.

Запрос блокируются до окончания выполнения и получения готового документа либо ошибки во время выполнения.


В асинхронном режиме, проверяется направление конвертации, затем параллельно запускается обработка задания на печать (наложение штампа)

Если конвертация не поддерживается то сразу возвращается ошибка о неприменимости такого действия (http 406)

По окончании задания на печать формируется отчет в топик кафки printer.report

Возможно прямое перенаправление асинхронных запросов в топики кафки. (MODE_REST_KAFKA_REDIRECT)

Предполагается, что  это предотвратит потерю результата в момент рестарта сервиса и не законченном задании на печать. 

Конечные точки

/normalize

Очищает плейсхолдеры в docx шаблоне от форматирования синхронно. 
Ворд может разбивать текст на отдельные блоки форматирования, ломая mustache.
Метод вырезает все xml-теги между фигурными скобками, присваивая стиль всему плейсхолдеру, как у открывающейся скобки.

/sync/{input}/to/{output}

Печатает шаблон синхронно в указанном формате (input) и конвертирует его в указанный формат (output), немедленно возвращает распечатанный документ как файл в http ответе


/stamp/sync/{input}/to/{output}
Добавляет штамп в документ синхронно в указанном формате (input) и конвертирует его в указанный формат (output), немедленно возвращает распечатанный документ как файл в http ответе


/sync/stamp-print/{input}/to/{output}
Печатает шаблон синхронно в указанном формате (input), накладывает штамп и конвертирует его в указанный формат (output), немедленно возвращает распечатанный документ как файл в http ответе


/async/{input}/to/{output}
Принимает шаблон в асинхронную печать


/stamp/async/{input}/to/{output}
Принимает документ для асинхронной печати штампа в указанном формате (input) и конвертирует его в указанный формат (output) и отсылает сообщение о статусе печати вместе с ссылкой на скачивание из S3 в Kafka Topic


/async/stamp-print/{input}/to/{output}
Принимает шаблон в асинхронную печать в указанном формате (input), накладывает штамп и конвертирует его в указанный формат (output) и отсылает сообщение о статусе печати вместе с ссылкой на скачивание из S3 в Kafka Topic


/selftest
самодиагностика сервиса 

возращает результат проверки функциональных возможностей

 docxPrint: SUCCESS,
 htmlPrint: SUCCESS,
 pdfStamp: SUCCESS,
 docxStamp: SUCCESS,
 htmlStampAfterPrint: SUCCESS,
 docxStampAfterPrint: SUCCESS
}


/swagger-ui
Доступен сваггер c описанием REST-методов

/health
Проверка работоспособности сервиса от micronaut

/prometheus
Точка предоставления метрик для Prometheus

Настройки

micronaut:
  application:
    name: printer
    default-charset: UTF-8
  server:
    port: ${SERVICE_PORT:8080}
 
  metrics:
    enabled: true
    export:
      prometheus:
        enabled: true
        step: PT1M
        descriptions: true
  heartbeat:
    enabled: false
  health:
    monitor:
      enabled: true
 
  router:
    static-resources:
      swagger-ui:
        paths: classpath:/swagger-ui
        mapping: /swagger-ui/**
 
  security:
    enabled: ${SECURITY_ENABLED:true} # вкл\выкл безопасности
    token:
      enabled: true # включаем token-based безопасность
      jwt:
        enabled: true
        bearer:
          enabled: true
 
logger:
  levels:
    root: ${PRINT_LOG_LEVEL:INFO}
    sx.microservices: ${SX_LOG_LEVEL:INFO}
 
s3:
  enabled: ${AWS_S3_ENABLED:true}
  url: ${AWS_ENDPOINT:`http://localhost:9011`}
  urlExternal: ${AWS_ENDPOINT_EXTERNAL:`http://localhost:9011`}
  key: ${AWS_ACCESS_KEY_ID:}
  secret: ${AWS_SECRET_ACCESS_KEY:}
  bucket: ${AWS_S3_BUCKET:printed-documents}
  bucket-suffix-enabled: ${AWS_S3_BUCKET_SUFFIX_ENABLED:false}
  bucket-create-if-not-exist: ${AWS_S3_BUCKET_CREATE_IF_NOT_EXIST:true}
  url-expire-in-seconds: ${AWS_S3_URL_EXPIRE_SECONDS:604800}
  url-presigned-enabled: ${AWS_S3_URL_PRESIGNED_ENABLED:true}
  health:
    enabled: ${AWS_S3_HEALTH_ENABLED:true}
    timeout: ${AWS_S3_HEALTH_TIMEOUT:3000ms}
    retries: ${AWS_S3_HEALTH_RETRIES:2}
 
redis:
  uri: ${REDIS_CONNECTION_STRING:`redis://localhost`}
  caches:
    print-processing-cache:
      expire-after-write: 2h
    stamp-processing-cache:
      expire-after-write: 2h
 
 
swagger:
  merge-files: false
  sso-endpoint: ${SSO_CLIENT_URL_HOST:`https://pgs2-uat-sso.test.gosuslugi.ru`}
 
#Настройки режима работы экземпляра сервиса
mode:
  #Режим работы через кафка
  kafka:
    enabled: true
    #Обработка заполнения шаблона, с последующей конвертацией
    print:
      enabled: true
    #Обработка подписания (наложения штампа подписанта)
    stamp:
      enabled: true
    #Обработка заполнения шаблона, затем наложения штампа
    print-stamp:
      enabled: true
    #Вкючить режим идемпотентной обработки сообщений
    idempotency: true
  #Режим работы через REST
  rest:
    enabled: true
    #перенаправлять асинхроные запросы в kafka топики
    kafka-redirect: true
 
printer-topics:
  report: ${KAFKA_TOPIC_PREFIX:}printer.report
  print-consumer: ${KAFKA_TOPIC_PREFIX:}printer.process.print
  stamp-consumer: ${KAFKA_TOPIC_PREFIX:}printer.process.stamp
  print-stamp-consumer: ${KAFKA_TOPIC_PREFIX:}printer.process.print-stamp
 
kafka:
  group-id-prefix: ${KAFKA_GROUP_PREFIX:}
  group-id-suffix: _${POD_NAME:}
  bootstrap:
    servers: ${KAFKA_HOSTS:`localhost:9092,localhost:9093,localhost:9094`}
  health:
    enabled: ${KAFKA_ENABLED:true}
  producers:
    default:
      retries: 3
  health-timeout: 4500ms
  max:
    poll:
      records: 500
      interval:
        ms: 300000
  #Таймаут на выполнение одного задания на печать, при работе через кафка
  print-task-execution: 4m
 
 
secure-configuration:
  token-validation:
    enabled: true
    trusted-issuers: ${TRUSTED_ISSUERS:}
  scopes:
    - printer
  userinfo-roles:
    enabled: true
    path: /userinfo
 
 
# Конфигурация библиотеки client-token-manager
token-manager:
  enabled: true
  # В случае невозможности использовать автоматическую конфигурацию OIDC, тут указывается Token Endpoint.
  token-endpoint: ${SSO_CLIENT_URL_HOST:`http://sso-service`}/token
  # Зарегистрированный client_id.
  client-id: ${SSO_CLIENT:printer-client}
  # Зарегистрированный client_secret.
  client-secret: ${SSO_CLIENT_SECRET:93456662-5e0c-4ea1-883c-fd6be4c82d29}
  # Необходимые для работы приложения скоупы.
  scope: openid,ClientScope1,service
  # За сколько секунд до окончания времени жизни токена нужно будет получить новый. По умолчанию 15 секунд.
  token-expires-in-skew: ${SSO_CLIENT_REFRESH_TOKEN_BEFORE:60s}
 
 
jackson:
  date-format: yyyy-MM-dd'T'HH:mm:ss.SSSXXX
 
 
endpoints:
  loggers:
    enabled: true
  health:
    enabled: true
    sensitive: false
    details-visible: ANONYMOUS # show details for everyone
  metrics:
    enabled: false
    sensitive: true
  prometheus:
    enabled: true
    sensitive: false
 
 
tracing:
  jaeger:
    enabled: ${JAEGER_ENABLED:false}
    exclude-paths:
      - /health
      - /prometheus
      - /favicon.ico
      - /api
      - /swagger-ui
    sampler:
      probability: ${JAEGER_SAMPLER_PROBABILITY:1}
    sender:
      agentHost: ${JAEGER_HOST:localhost}
      agentPort: ${JAEGER_PORT:6831}
 
libreoffice:
  enabled: ${LIBREOFFICE_ENABLED:true}
  office-home: /usr/lib/libreoffice
  portNumbers: 8105,8104,8103,8102,8101
  maxTasksPerProcess: 100
  taskExecutionTimeout: 30000
  process-timeout: 5000
  startFailFast: true
  remote:
    enabled: false
    connectTimeout: 60000 # минута
    socketTimeout: 12000 # 2 минуты
    poolSize: 1
 
#Предпочтения конвертеров
converters:
  #input
  html:
    #output
    pdf:
    - HtmlToPdfLibreOfficeConverter
    - OpenHtmlToPdfConverter
    - WkHtmlToPdfConverter
    - SauseHtmlToPdfConverter
    docx:
    - HtmlToDocxLibreOfficeConverter
    - HtmlToDocxConverter
  #input
  docx:
    #output
    pdf:
    - DocxToPdfLibreOfficeConverter
    - ApacheDocxToPdfConverter


Журналирование

Логирование в json формате включается переменной окружения JSON_ENABLE=true
Уровень логирования указывается в переменной окружения PRINT_LOG_LEVEL=INFO (ERROR,INFO,DEBUG)

Необходимые ресурсы окружения сервиса

sso

переменная окружения TOKEN_MANAGER_TOKEN_ENDPOINT


kafka

переменная окружения KAFKA_HOSTS

redis

переменная окружения REDIS_CONNECTION_STRING

s3 

переменные окружения

AWS_ENDPOINT
AWS_ENDPOINT_EXTERNAL

jaeger

переменные окружения

JAEGER_HOST
JAEGER_PORT

kubernetess

Для старта приложения требуется примерно от 15 до 30 секунд, поэтому стартап проба должна быть от этих значений.

Для остальных проб(readiness,liveness) нужно использовать подготовленный внутри образа скрипт

/readiness.sh

В случае успешной проверки он возвращает exit_code=0 иначе exit_code>0

Внутри скрипта выполняются проверки на соответствие

количества экземпляров  libreOffice запущенных сейчас  с количеством указанных в настройках при старте экземпляра сервиса.

затем проверка на доступность http, так как он также является индикатором для успешного старта экземпляра сервиса


Мониторинг

Предусматривает несколько графиков регистрирующих количество запросов функционала (печать,штамп,штамп+печать) и количество ответов, по одному на каждый функционал

Также на каждый функционал имеются графики с ошибками. Их два: первый в разрезе направления конвертации, второй детальный по тексту ошибки и экземплярам сервисов.


Метрики которые реализованы для экспорта в Prometheus (являются счетчиками)

printRequest
stampRequest
printStampRequest

printCompleted
stampCompleted
printStampCompleted

printError
stampError
printStampError


для всех метрик добавляются следующие теги

from, to, fileName

traceId, podName

для режима работы через кафку также добавляется тэг kafka=true

в режиме обработки через кафку также добавляется тэг retryCount, если он присутствовал в заголовке исходного сообщения кафки.

retryCount ( счетчик повторов для одного задания на печать/штамп)


для метрик с суффиксом Error, добавляется тэг duration и error (с текстом ошибки)

для метрик с суффиксом Completed,  добавляется также тэг duration (время в секундах прошедшее с начала обработки задания печати/штампа) 


Примеры:

Формирование заявления

Для формирования используется шаблон template_HuntingResourcesResult_0_2.docx  и данные json из файла HuntingResourcesResult_0_2.json

curl -X POST https://pgs2-uat.test.gosuslugi.ru/service/printer/sync/DOCX/to/DOCX \
-H 'Authorization: Bearer eyJraWQiOiJzc29rZXkxIiwidHlwIjoiSldUIiwiYWxnIjoiUlM1MTIifQ.eyJzdWIiOiIyMmRlYTM0MS1mNWU0LTRiOGMtOGU4My05NDMxZDQwMzdkOTIiLCJhbXIiOlsiSURQX0xPQ0FMIl0sInJvbGVzIjpbItCR0LDQt9C-0LLQsNGPINGA0L7Qu9GMINC00LvRjyDQsNCy0YLQvtGA0LjQt9Cw0YbQuNC4Iiwi0J_QvtC70YzQt9C-0LLQsNGC0LXQu9GM0YHQutCw0Y8g0YDQvtC70YwiLCLQoNC10LPQuNGB0YLRgNCw0YLQvtGAIiwi0J3QsNC30L3QsNGH0LDRjtGJ0LjQuSDRgNC10LPQuNGB0YLRgNCw0YLQvtGAIiwi0KHQv9C10YbQuNCw0LvQuNGB0YIiLCLQlNC-0LvQttC90L7RgdGC0L3QvtC1INC70LjRhtC-INGBINC_0L7QtNC_0LjRgdGM0Y4iLCLQndCw0LfQvdCw0YfQsNGO0YnQuNC5INGB0L_QtdGG0LjQsNC70LjRgdGCIiwicHJlb3JkZXJfYWRtaW4iLCJzZXJ2aWNlc0NvbnN0cnVjdCIsIlMzQ2xpZW50IiwicGVyc29uYWxSZWNlcHRpb24iXSwiaXNzIjoiaHR0cHM6XC9cL3BnczItdWF0LXNzby50ZXN0Lmdvc3VzbHVnaS5ydSIsImdyb3VwcyI6W10sImRvbWFpbl9pZCI6IjZiNTdmYmY3LTc5MTAtNGQwNy1iNmU3LTQ3YmU5YjlhZjVkZSIsImF1ZCI6ImFybSIsImFjY291bnRJZCI6IjIyZGVhMzQxLWY1ZTQtNGI4Yy04ZTgzLTk0MzFkNDAzN2Q5MiIsIm5iZiI6MCwiYXpwIjoiYXJtIiwiYXV0aF90aW1lIjowLCJuYW1lIjoi0JzQvtC70L7QutC-0LLRgdC60LjRhSDQodC10YDQs9C10LkiLCJyZWFsbSI6IkZpcm1hIG1vZGEiLCJleHAiOjE2Nzg5NTE4MzcsInNlc3Npb25fc3RhdGUiOiI3ZmQ2YWE3OS1mNDg1LTQ0YTctOTM4Ny1lYTAyMDhkMDZlMjEiLCJpYXQiOjE2Nzg5NDgyMzd9.IU1EuZ3Uh8PuZjmkUBktzesiZlU7PilAICuZM6-tKaZq7qS6NmC6tK5-4s5BWPm5BFpE2VkMlzOnBzFVnikjGzKcQ2QY40j8L6kEgUADN6jzE3xpQyI_IGnppFXpkurVgeHUlF2jKFTXrAZpektFClbqDmqYJM4nEvp7HGbLjurFixX23v8EcS5HIIN97lhTJaHqzir1keg427W4FhGL4f9sxkbXWenBDkMxDQA0lzWgNZeFL5khSNgPUr9ovIiHN_CmuKQy3gkS756k7QNe75LANdXd-Chaziz7M4Qmjjv6MM1CGSaPhOrqeVsUZI9cKeCFBlTLGfsxVCXuk_dG6w' \
-H 'Content-Type: multipart/form-data' \
-F 'template=@template_HuntingResourcesResult_0_2.docx' \
-F 'parameters=@HuntingResourcesResult_0_2.json' \
-o HuntingResourcesResult_0_2.docx


Формирование межведомственного запроса

Для формирования используется шаблон template_EGRUL-INN.html и данные json

curl -X POST https://pgs2-uat.test.gosuslugi.ru/service/printer/sync/stamp-print/HTML/to/PDF \
-H 'Authorization: Bearer eyJraWQiOiJzc29rZXkxIiwidHlwIjoiSldUIiwiYWxnIjoiUlM1MTIifQ.eyJzdWIiOiIyMmRlYTM0MS1mNWU0LTRiOGMtOGU4My05NDMxZDQwMzdkOTIiLCJhbXIiOlsiSURQX0xPQ0FMIl0sInJvbGVzIjpbItCR0LDQt9C-0LLQsNGPINGA0L7Qu9GMINC00LvRjyDQsNCy0YLQvtGA0LjQt9Cw0YbQuNC4Iiwi0J_QvtC70YzQt9C-0LLQsNGC0LXQu9GM0YHQutCw0Y8g0YDQvtC70YwiLCLQoNC10LPQuNGB0YLRgNCw0YLQvtGAIiwi0J3QsNC30L3QsNGH0LDRjtGJ0LjQuSDRgNC10LPQuNGB0YLRgNCw0YLQvtGAIiwi0KHQv9C10YbQuNCw0LvQuNGB0YIiLCLQlNC-0LvQttC90L7RgdGC0L3QvtC1INC70LjRhtC-INGBINC_0L7QtNC_0LjRgdGM0Y4iLCLQndCw0LfQvdCw0YfQsNGO0YnQuNC5INGB0L_QtdGG0LjQsNC70LjRgdGCIiwicHJlb3JkZXJfYWRtaW4iLCJzZXJ2aWNlc0NvbnN0cnVjdCIsIlMzQ2xpZW50IiwicGVyc29uYWxSZWNlcHRpb24iXSwiaXNzIjoiaHR0cHM6XC9cL3BnczItdWF0LXNzby50ZXN0Lmdvc3VzbHVnaS5ydSIsImdyb3VwcyI6W10sImRvbWFpbl9pZCI6IjZiNTdmYmY3LTc5MTAtNGQwNy1iNmU3LTQ3YmU5YjlhZjVkZSIsImF1ZCI6ImFybSIsImFjY291bnRJZCI6IjIyZGVhMzQxLWY1ZTQtNGI4Yy04ZTgzLTk0MzFkNDAzN2Q5MiIsIm5iZiI6MCwiYXpwIjoiYXJtIiwiYXV0aF90aW1lIjowLCJuYW1lIjoi0JzQvtC70L7QutC-0LLRgdC60LjRhSDQodC10YDQs9C10LkiLCJyZWFsbSI6IkZpcm1hIG1vZGEiLCJleHAiOjE2Nzg5NTE4MzcsInNlc3Npb25fc3RhdGUiOiI3ZmQ2YWE3OS1mNDg1LTQ0YTctOTM4Ny1lYTAyMDhkMDZlMjEiLCJpYXQiOjE2Nzg5NDgyMzd9.IU1EuZ3Uh8PuZjmkUBktzesiZlU7PilAICuZM6-tKaZq7qS6NmC6tK5-4s5BWPm5BFpE2VkMlzOnBzFVnikjGzKcQ2QY40j8L6kEgUADN6jzE3xpQyI_IGnppFXpkurVgeHUlF2jKFTXrAZpektFClbqDmqYJM4nEvp7HGbLjurFixX23v8EcS5HIIN97lhTJaHqzir1keg427W4FhGL4f9sxkbXWenBDkMxDQA0lzWgNZeFL5khSNgPUr9ovIiHN_CmuKQy3gkS756k7QNe75LANdXd-Chaziz7M4Qmjjv6MM1CGSaPhOrqeVsUZI9cKeCFBlTLGfsxVCXuk_dG6w' \
-H 'Content-Type: multipart/form-data' \
-F 'template=@template_EGRUL-INN.html' \
-F 'parameters={
  "rightText": "Текст справа",
  "leftText": "Текст слева",
  "certificate": "MIIDtDCCA2OgAwIBAgITEgBfwqhLIsIXlM6p7QABAF/CqDAIBgYqhQMCAgMwfzEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBjcnlwdG9wcm8ucnUxCzAJBgNVBAYTAlJVMQ8wDQYDVQQHEwZNb3Njb3cxFzAVBgNVBAoTDkNSWVBUTy1QUk8gTExDMSEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDIwHhcNMjIwOTE1MTI0NjQzWhcNMjIxMjE1MTI1NjQzWjCBuDEvMC0GA1UEAwwm0J/QvtC/0L7QstCwINCQ0L3QvdCwINCY0LPQvtGA0LXQstC90LAxgYQwgYEGA1UECgx60JfQsNC80LXRgdGC0LjRgtC10LvRjCDQvdCw0YfQsNC70YzQvdC40LrQsCDRg9C/0YDQsNCy0LvQtdC90LjRjywg0L3QsNGH0LDQu9GM0L3QuNC6INC+0YLQtNC10LvQsCDQs9GA0LDQtNC+0YHRgtGA0L7QuNGC0LUwZjAfBggqhQMHAQEBATATBgcqhQMCAiQABggqhQMHAQECAgNDAARAtygzTSOENmXekFekmqaKLZPQ42aWGrrbz19ogYGRuNr28PeGIdZL43/RjY76a00y60vztnCuiApZprMhrRZXqKOCAXcwggFzMA8GA1UdDwEB/wQFAwMH8AAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0OBBYEFK1se3cYcP9GAMyZtrksajRC2uU7MB8GA1UdIwQYMBaAFE6DPhRp7+xdepUrXxH+NzIWSVUrMFwGA1UdHwRVMFMwUaBPoE2GS2h0dHA6Ly90ZXN0Y2EuY3J5cHRvcHJvLnJ1L0NlcnRFbnJvbGwvQ1JZUFRPLVBSTyUyMFRlc3QlMjBDZW50ZXIlMjAyKDEpLmNybDCBrAYIKwYBBQUHAQEEgZ8wgZwwZAYIKwYBBQUHMAKGWGh0dHA6Ly90ZXN0Y2EuY3J5cHRvcHJvLnJ1L0NlcnRFbnJvbGwvdGVzdC1jYS0yMDE0X0NSWVBUTy1QUk8lMjBUZXN0JTIwQ2VudGVyJTIwMigxKS5jcnQwNAYIKwYBBQUHMAGGKGh0dHA6Ly90ZXN0Y2EuY3J5cHRvcHJvLnJ1L29jc3Avb2NzcC5zcmYwCAYGKoUDAgIDA0EAsdDYX/XEtjJ/YtqnJT/Ip5oHZUPfDbJb8bRMh4s4xabl62dHxhdi1rmSm5G+87y7zCcdOvM7VsYABdzwn5WjeA=="
}' \
-o EGRUL-INN.pdf

Написать комментарий...